/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * MainGUI.java
 *
 * Created on 23/11/2011, 18:10:30
 */
package edu.sjb.gui;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.io.IOException;

import javax.swing.GroupLayout;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;

import org.ini4j.Ini;
import org.ini4j.InvalidFileFormatException;

import edu.sjb.AppLauncher;
import edu.sjb.characters.Mario;
import edu.sjb.map.GenericMapElement;
import edu.sjb.map.LogicMapElement;
import edu.sjb.map.Map;
import edu.sjb.map.MapLoader;
import edu.sjb.thread.ColisionThread;
import edu.sjb.thread.MarioLeftUpdaterThread;
import edu.sjb.thread.MarioRightUpdaterThread;
import edu.sjb.thread.MarioUpUpdaterThread;
import edu.sjb.tools.ExtensionFilter;


/**
* This code was edited or generated using CloudGarden's Jigloo
* SWT/Swing GUI Builder, which is free for non-commercial
* use. If Jigloo is being used commercially (ie, by a corporation,
* company or business for any purpose whatever) then you
* should purchase a license for each developer using Jigloo.
* Please visit www.cloudgarden.com for details.
* Use of Jigloo implies acceptance of these licensing terms.
* A COMMERCIAL LICENSE HAS NOT BEEN PURCHASED FOR
* THIS MACHINE, SO JIGLOO OR THIS CODE CANNOT BE USED
* LEGALLY FOR ANY CORPORATE OR COMMERCIAL PURPOSE.
*/
/**
 *
 * @author francisco
 */

@SuppressWarnings("serial")
public class MainGUI extends javax.swing.JFrame implements KeyListener{

    /** Creates new form MainGUI */
    public MainGUI() {
        initComponents();
        
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */

    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        gameLayPane = new javax.swing.JLayeredPane();
        backgroundPanel = new javax.swing.JPanel();
        bricksPanel = new javax.swing.JPanel();
        marioPanel = new javax.swing.JPanel();
        statusPanel = new javax.swing.JPanel();
        scoreLabel = new javax.swing.JLabel();
        debugPositionLabel = new javax.swing.JLabel();
        menuBar = new javax.swing.JMenuBar();
        gameMenu = new javax.swing.JMenu();
        levelMenu = new javax.swing.JMenu();
        loadLevelMenuItem = new javax.swing.JMenuItem();
        restartLevelMenuItem = new javax.swing.JMenuItem();
        abandonLevelMenuItem = new javax.swing.JMenuItem();
        levelMenuSeparator = new javax.swing.JPopupMenu.Separator();
        highScoresMenuItem = new javax.swing.JMenuItem();
        gameMenuSeparator1 = new javax.swing.JPopupMenu.Separator();
        skinMenu = new javax.swing.JMenu();
        skinUseDefaultSkinRadioMenu = new javax.swing.JRadioButtonMenuItem();
        skinUseCustomSkinRadioMenu = new javax.swing.JRadioButtonMenuItem();
        gameMenuSeparator2 = new javax.swing.JPopupMenu.Separator();
        quitGameMenuItem = new javax.swing.JMenuItem();
        helpMenu = new javax.swing.JMenu();
        controlsHelpMenuItem = new javax.swing.JMenuItem();
        aboutMenuItem = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle(AppLauncher.APPNAME);

        gameLayPane.setPreferredSize(new java.awt.Dimension(800, 640));

        backgroundPanel.setBackground(java.awt.Color.cyan);
        backgroundPanel.setBorder(null);

        javax.swing.GroupLayout backgroundPanelLayout = new javax.swing.GroupLayout(backgroundPanel);
        backgroundPanel.setLayout(backgroundPanelLayout);
        backgroundPanelLayout.setHorizontalGroup(
            backgroundPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 800, Short.MAX_VALUE)
        );
        backgroundPanelLayout.setVerticalGroup(
            backgroundPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 640, Short.MAX_VALUE)
        );

        backgroundPanel.setBounds(0, 0, 800, 640);
        gameLayPane.add(backgroundPanel, javax.swing.JLayeredPane.DEFAULT_LAYER);

        bricksPanel.setBorder(null);
        bricksPanel.setOpaque(false);

        javax.swing.GroupLayout bricksPanelLayout = new javax.swing.GroupLayout(bricksPanel);
        bricksPanel.setLayout(bricksPanelLayout);
        bricksPanelLayout.setHorizontalGroup(
            bricksPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 800, Short.MAX_VALUE)
        );
        bricksPanelLayout.setVerticalGroup(
            bricksPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 640, Short.MAX_VALUE)
        );

        bricksPanel.setBounds(0, 0, 800, 640);
        gameLayPane.add(bricksPanel, javax.swing.JLayeredPane.PALETTE_LAYER);

        marioPanel.setOpaque(false);

        javax.swing.GroupLayout marioPanelLayout = new javax.swing.GroupLayout(marioPanel);
        marioPanel.setLayout(marioPanelLayout);

        marioPanel.setBounds(0, 0, 800, 640);
        gameLayPane.add(marioPanel, javax.swing.JLayeredPane.POPUP_LAYER);
        mario = new Mario();
        marioPanel.add(mario);
        marioPanelLayout.setVerticalGroup(marioPanelLayout.createSequentialGroup()
        	.addComponent(mario, GroupLayout.PREFERRED_SIZE, 64, GroupLayout.PREFERRED_SIZE)
        	.addContainerGap(572, Short.MAX_VALUE));
        marioPanelLayout.setHorizontalGroup(marioPanelLayout.createSequentialGroup()
        	.addComponent(mario, GroupLayout.PREFERRED_SIZE, 32, GroupLayout.PREFERRED_SIZE)
        	.addContainerGap(760, Short.MAX_VALUE));

        statusPanel.setOpaque(false);

        scoreLabel.setText("Puntaje: " + score);

        debugPositionLabel.setText("");

        javax.swing.GroupLayout statusPanelLayout = new javax.swing.GroupLayout(statusPanel);
        statusPanel.setLayout(statusPanelLayout);
        statusPanelLayout.setHorizontalGroup(
            statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(statusPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(scoreLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 599, Short.MAX_VALUE)
                .addComponent(debugPositionLabel)
                .addContainerGap())
        );
        statusPanelLayout.setVerticalGroup(
            statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(statusPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(scoreLabel)
                    .addComponent(debugPositionLabel))
                .addContainerGap(587, Short.MAX_VALUE))
        );

        statusPanel.setBounds(0, 0, 800, 616);
        gameLayPane.add(statusPanel, javax.swing.JLayeredPane.DRAG_LAYER);

        gameMenu.setMnemonic('j');
        gameMenu.setText("Juego");

        levelMenu.setMnemonic('n');
        levelMenu.setText("Nivel");

        loadLevelMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_L, java.awt.event.InputEvent.CTRL_MASK));
        loadLevelMenuItem.setMnemonic('c');
        loadLevelMenuItem.setText("Cargar...");
        loadLevelMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                loadLevelMenuItemActionPerformed(evt);
            }
        });
        levelMenu.add(loadLevelMenuItem);

        restartLevelMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_N, java.awt.event.InputEvent.CTRL_MASK));
        restartLevelMenuItem.setMnemonic('i');
        restartLevelMenuItem.setText("Iniciar/Reiniciar");
        restartLevelMenuItem.setEnabled(false);
        restartLevelMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                restartLevelMenuItemActionPerformed(evt);
            }
        });
        levelMenu.add(restartLevelMenuItem);

        abandonLevelMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_ESCAPE, java.awt.event.InputEvent.CTRL_MASK));
        abandonLevelMenuItem.setMnemonic('a');
        abandonLevelMenuItem.setText("Abandonar");
        abandonLevelMenuItem.setEnabled(false);
        abandonLevelMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                abandonLevelMenuItemActionPerformed(evt);
            }
        });
        levelMenu.add(abandonLevelMenuItem);

        levelMenuSeparator.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        levelMenu.add(levelMenuSeparator);

        highScoresMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_H, java.awt.event.InputEvent.CTRL_MASK));
        highScoresMenuItem.setMnemonic('m');
        highScoresMenuItem.setText("Mejores puntajes...");
        highScoresMenuItem.setEnabled(false);
        highScoresMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                highScoresMenuItemActionPerformed(evt);
            }
        });
        levelMenu.add(highScoresMenuItem);

        gameMenu.add(levelMenu);

        gameMenuSeparator1.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        gameMenu.add(gameMenuSeparator1);

        skinMenu.setMnemonic('s');
        skinMenu.setText("Skin");

        skinUseDefaultSkinRadioMenu.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S, java.awt.event.InputEvent.CTRL_MASK));
        skinUseDefaultSkinRadioMenu.setMnemonic('d');
        skinUseDefaultSkinRadioMenu.setSelected(true);
        skinUseDefaultSkinRadioMenu.setText("Skin por defecto");
        skinUseDefaultSkinRadioMenu.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                skinUseDefaultSkinRadioMenuActionPerformed(evt);
            }
        });
        skinMenu.add(skinUseDefaultSkinRadioMenu);

        skinUseCustomSkinRadioMenu.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S, java.awt.event.InputEvent.SHIFT_MASK | java.awt.event.InputEvent.CTRL_MASK));
        skinUseCustomSkinRadioMenu.setMnemonic('p');
        skinUseCustomSkinRadioMenu.setText("Skin personalizado...");
        skinUseCustomSkinRadioMenu.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                skinUseCustomSkinRadioMenuActionPerformed(evt);
            }
        });
        skinMenu.add(skinUseCustomSkinRadioMenu);

        gameMenu.add(skinMenu);

        gameMenuSeparator2.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        gameMenu.add(gameMenuSeparator2);

        quitGameMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_Q, java.awt.event.InputEvent.CTRL_MASK));
        quitGameMenuItem.setMnemonic('a');
        quitGameMenuItem.setText("Salir");
        quitGameMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                quitGameMenuItemActionPerformed(evt);
            }
        });
        gameMenu.add(quitGameMenuItem);

        menuBar.add(gameMenu);

        helpMenu.setMnemonic('a');
        helpMenu.setText("Ayuda");

        controlsHelpMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F1, 0));
        controlsHelpMenuItem.setMnemonic('c');
        controlsHelpMenuItem.setText("Controles");
        controlsHelpMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                controlsHelpMenuItemActionPerformed(evt);
            }
        });
        helpMenu.add(controlsHelpMenuItem);

        aboutMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F1, java.awt.event.InputEvent.SHIFT_MASK));
        aboutMenuItem.setMnemonic('a');
        aboutMenuItem.setText("Acerca de...");
        aboutMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                aboutMenuItemActionPerformed(evt);
            }
        });
        helpMenu.add(aboutMenuItem);

        menuBar.add(helpMenu);

        setJMenuBar(menuBar);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        this.addKeyListener(this);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(gameLayPane, javax.swing.GroupLayout.PREFERRED_SIZE, 800, javax.swing.GroupLayout.PREFERRED_SIZE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(gameLayPane, javax.swing.GroupLayout.PREFERRED_SIZE, 640, javax.swing.GroupLayout.PREFERRED_SIZE)
        );
        
        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void loadLevelMenuItemActionPerformed(java.awt.event.ActionEvent evt) {
    //	levelMap = new Map(1,1);
        JFileChooser fc = new JFileChooser("./levels/");
        ExtensionFilter ef = new ExtensionFilter("Super JAVA Bros level (*.sjl)", ".sjl");
        fc.addChoosableFileFilter(ef);
        fc.setFileFilter(ef);
        int result = fc.showOpenDialog(null);
        if (result == JFileChooser.APPROVE_OPTION) {
            File chosen = fc.getSelectedFile();
            Ini iniFile;
			try {
				iniFile = new Ini(chosen);
				levelMap=MapLoader.loadMapFromIni(iniFile);
			} 
			catch (InvalidFileFormatException e) {
				
				System.out.println(e.getMessage());
			} 
			catch (IOException e) {
				System.out.println(e.getMessage());
			}
            
        }
        else {
            JOptionPane.showMessageDialog(null,
                    "File opening cancelled by user. Super Java Bros will exit.",
                    "Level loading cancelled",
                    JOptionPane.INFORMATION_MESSAGE);
        }
        
        int mapWidth = levelMap.getWidth();
        int mapHeigth = levelMap.getHeigth();
        
        for (int h = mapHeigth-1; h >= 0; h--)  {
            for (int w = 0; w < mapWidth; w++) {
                JLabel currentJL = new JLabel();
                currentJL.setIcon(levelMap.getElementAt(w, h).getImage());
                currentJL.setSize(32,32);
                currentJL.setLocation(w*32, h*32);
                bricksPanel.add(currentJL);
            }
        }
        
        repaint();
        colision= new ColisionThread();
        colision.start();
        
    }

    private void restartLevelMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_restartLevelMenuItemActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_restartLevelMenuItemActionPerformed

    private void abandonLevelMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_abandonLevelMenuItemActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_abandonLevelMenuItemActionPerformed

    private void highScoresMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_highScoresMenuItemActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_highScoresMenuItemActionPerformed

    private void skinUseDefaultSkinRadioMenuActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_skinUseDefaultSkinRadioMenuActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_skinUseDefaultSkinRadioMenuActionPerformed

    private void skinUseCustomSkinRadioMenuActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_skinUseCustomSkinRadioMenuActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_skinUseCustomSkinRadioMenuActionPerformed

    private void quitGameMenuItemActionPerformed(java.awt.event.ActionEvent evt) {
        System.exit(0);
    }

    private void controlsHelpMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_controlsHelpMenuItemActionPerformed
        JOptionPane.showMessageDialog(this,
                "Los controles b\u00e1sicos son:\n"
                + "  Mover a izquierda: FLECHA IZQUIERDA\n"
                + "  Mover a derecha: FLECHA DERECHA\n"
                + "  Saltar: ESPACIO\n"
                + "  Lanzar bolas de fuego: X",
                AppLauncher.APPNAME,
                JOptionPane.INFORMATION_MESSAGE);
    }//GEN-LAST:event_controlsHelpMenuItemActionPerformed

    private void aboutMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_aboutMenuItemActionPerformed
        JOptionPane.showMessageDialog(this,
                AppLauncher.APPNAME + " " + AppLauncher.APPVERSION + "\n"
                + "Dise\u00f1ado por Francisco C\u00e1neva [92817] y Federico Nieto [74637]\n"
                + "para la materia Tecnolog\u00eda de la Programaci\u00f3n de la Universidad Nacional del Sur.\n"
                + "Segundo cuatrimestre de 2011",
                AppLauncher.APPNAME,
                JOptionPane.INFORMATION_MESSAGE);
    }//GEN-LAST:event_aboutMenuItemActionPerformed

    public Mario mario() {
        return mario;
    }
    
    public Map map() {
        return levelMap;
    }
    

    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JMenuItem abandonLevelMenuItem;
    private javax.swing.JMenuItem aboutMenuItem;
    private javax.swing.JPanel backgroundPanel;
    private javax.swing.JPanel bricksPanel;
    private javax.swing.JMenuItem controlsHelpMenuItem;
    private javax.swing.JLabel debugPositionLabel;
    private javax.swing.JLayeredPane gameLayPane;
    private javax.swing.JMenu gameMenu;
    private javax.swing.JPopupMenu.Separator gameMenuSeparator1;
    private javax.swing.JPopupMenu.Separator gameMenuSeparator2;
    private javax.swing.JMenu helpMenu;
    private javax.swing.JMenuItem highScoresMenuItem;
    private javax.swing.JMenu levelMenu;
    private javax.swing.JPopupMenu.Separator levelMenuSeparator;
    private javax.swing.JMenuItem loadLevelMenuItem;
    private javax.swing.JPanel marioPanel;
    private javax.swing.JMenuBar menuBar;
    private javax.swing.JMenuItem quitGameMenuItem;
    private javax.swing.JMenuItem restartLevelMenuItem;
    private javax.swing.JLabel scoreLabel;
    private javax.swing.JMenu skinMenu;
    private javax.swing.JRadioButtonMenuItem skinUseCustomSkinRadioMenu;
    private javax.swing.JRadioButtonMenuItem skinUseDefaultSkinRadioMenu;
    private javax.swing.JPanel statusPanel;
    // End of variables declaration//GEN-END:variables
    
    private boolean eventLeftLock = false;
    private boolean eventRightLock = false;
    private boolean eventUpLock = false;
    private Map levelMap;
    private Mario mario;
    private MarioLeftUpdaterThread marioLeft;
    private MarioRightUpdaterThread marioRight;
    private MarioUpUpdaterThread marioUp;
    private ColisionThread colision;
    
    //Score-related items
    private int score = 0;

	@Override
	public void keyPressed(KeyEvent arg0) {
    	switch (arg0.getKeyCode()) {
			case KeyEvent.VK_LEFT:
				if(!eventLeftLock) {
					mario.goIzquierda();
					mario.setState(mario.LEFT);
					eventLeftLock = true;
					if( marioLeft == null )
					{
						marioLeft = new MarioLeftUpdaterThread(mario);
						marioLeft.start();

					}
				}
				break;
			case KeyEvent.VK_RIGHT:
				if(!eventRightLock) {
					mario.goDerecha();
					mario.setState(mario.RIGTH);
					eventRightLock = true;
					if( marioRight == null )
					{
						marioRight = new MarioRightUpdaterThread(mario);
						marioRight.start();

					}
				}

				break;
			case KeyEvent.VK_SPACE:
				if (!eventUpLock)
				{
					int s= mario.getState();
					if (s == mario.LEFT)
					{
						mario.goSaltoL();
					}
					else
					{
						mario.goSaltoR();
					}
					
					mario.setState(mario.JUMP);
					eventRightLock = false;
					marioUp = new MarioUpUpdaterThread(mario);
					marioUp.start();
					eventUpLock = true;
			
				}
				break;
		}
	}

	@Override
	public void keyReleased(KeyEvent arg0) {	
		switch (arg0.getKeyCode()) {
		case KeyEvent.VK_LEFT:
			mario.goQuieto();
			mario.setState(mario.NO_MOVE);
			eventLeftLock = false;
			marioLeft.stop();
			marioLeft = null;

			break;
		case KeyEvent.VK_RIGHT:
			mario.goQuieto();
			mario.setState(mario.NO_MOVE);
			eventRightLock = false;
			marioRight.stop();
			marioRight = null;

			break;
		case KeyEvent.VK_SPACE:
			eventUpLock = false;
			mario.prevStatus();
			break;
		}	
	}

	@Override
	public void keyTyped(KeyEvent arg0) {
		
	}
    
}